﻿// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Website: https://www.blazor.zone or https://argozhang.github.io/

using Microsoft.AspNetCore.Components;
using SupperTreeSample.Shared.Data;

namespace SupperTreeSample.Shared.Components;

public partial class IngredientTable : ComponentBase
{
    [Parameter]
    [EditorRequired]
    [NotNull]
    public Food? Value { get; set; }

    [Parameter]
    public Func<Food, Task>? OnValueChanged { get; set; }

    [Inject]
    [NotNull]
    private ToastService? ToastService { get; set; }

    private Ingredient? EditingIngredient { get; set; }

    private Ingredient? OriginalIngredien { get; set; }

    private List<Ingredient> Items => Value?.Ingredients ?? new List<Ingredient>();

    private string? GetRowClassString(Ingredient ingredient) => IsEditing(ingredient) ? "is-edit" : null;

    private bool IsEditing(Ingredient ingredient) => EditingIngredient == ingredient;

    private Task<IEnumerable<string>> OnFilter(string name)
    {
        // name 为使用者输入汉字
        // 通过包含输入汉字条件过滤所有符合条件的食材 取 前 50 个
        var items = FoodGenerator.GenerateIngredient().Where(i => i.Name.Contains(name)).Take(50).Select(i => i.Name);
        return Task.FromResult(items);
    }

    private Task OnIngredientChanged(string name)
    {
        // 此方法是编辑表格内单元格时触发
        // 通过当前单元格内的文字获取食材信息
        var ingredient = FoodGenerator.GenerateIngredient().FirstOrDefault(i => i.Name == name);
        if (ingredient != null)
        {
            if (EditingIngredient != null)
            {
                // 获取当前食材索引
                var index = Value.Ingredients.IndexOf(EditingIngredient);
                Value.Ingredients.Remove(EditingIngredient);

                // 在当前位置插入新食材
                Value.Ingredients.Insert(index, ingredient);
                EditingIngredient = ingredient;
                StateHasChanged();
            }
        }
        return Task.CompletedTask;
    }

    private Task Update(Ingredient ingredient)
    {
        // 此方法时食材编辑时点击右侧 Update 按钮时触发
        OriginalIngredien = ingredient;
        EditingIngredient = ingredient;
        return Task.CompletedTask;
    }

    private Task Add(Ingredient ingredient)
    {
        // 在当前行下方插入直接进入编辑状态
        var index = Value.Ingredients.IndexOf(ingredient);
        var ingre = FoodGenerator.GenerateIngredient().FirstOrDefault(i => i.Name == ingredient.Name) ?? FoodGenerator.NewIngredient(ingredient);
        Value.Ingredients.Insert(index + 1, ingre);
        EditingIngredient = ingre;
        OriginalIngredien = ingre;
        return Task.CompletedTask;
    }

    private async Task Delete(Ingredient ingredient)
    {
        // 仅剩一个食材时不能删除食材
        if (Value.Ingredients.Count > 1)
        {
            Value.Ingredients.Remove(ingredient);
            StateHasChanged();
        }
        else
        {
            await ToastService.Information("删除食材操作", "请使用编辑食材功能");
        }
    }

    private void MovePrev(Ingredient ingredient)
    {
        var index = Value.Ingredients.IndexOf(ingredient);
        if (index > 0)
        {
            Value.Ingredients.Remove(ingredient);
            Value.Ingredients.Insert(index - 1, ingredient);
        }
    }

    private void MoveNext(Ingredient ingredient)
    {
        var index = Value.Ingredients.IndexOf(ingredient);
        var last = Value.Ingredients.Count - 1;
        if (index < last)
        {
            Value.Ingredients.Remove(ingredient);
            Value.Ingredients.Insert(index + 1, ingredient);
        }
    }

    private void MoveFirst(Ingredient ingredient)
    {
        var index = Value.Ingredients.IndexOf(ingredient);
        if (index > 0)
        {
            Value.Ingredients.Remove(ingredient);
            Value.Ingredients.Insert(0, ingredient);
        }
    }

    private void MoveLast(Ingredient ingredient)
    {
        var index = Value.Ingredients.IndexOf(ingredient);
        var last = Value.Ingredients.Count - 1;
        if (index < last)
        {
            Value.Ingredients.Remove(ingredient);
            Value.Ingredients.Add(ingredient);
        }
    }

    private void Cancel(Ingredient ingredient)
    {
        if (OriginalIngredien != null)
        {
            var index = Value.Ingredients.IndexOf(ingredient);
            Value.Ingredients.Remove(ingredient);
            Value.Ingredients.Insert(index, OriginalIngredien);
            EditingIngredient = null;
            OriginalIngredien = null;
            StateHasChanged();
        }
    }

    private async Task Save()
    {
        OriginalIngredien = null;
        EditingIngredient = null;
        if (OnValueChanged != null)
        {
            await OnValueChanged(Value);
        }
        StateHasChanged();
    }
}
